package editorsvg.propiedades;

import editorsvg.editor.atributos.Atributo;
import editorsvg.editor.comandos.ComandoCambiarPropiedad;
import editorsvg.editor.comandos.GestorComandos;
import editorsvg.editor.serializacion.AtributoXml;
import editorsvg.gui.generico.Actualizable;
import java.lang.reflect.Method;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JComponent;

/**
 * Clase base para la implementeción de las propiedades.
 *
 * @author Jorge Berjano
 */
public class Propiedad implements AtributoXml {

    private String nombreCampo;
    private String nombreAtributoXml;
    private GestorComandos gestorComandos;
    private Object propietario;
    
    private String valorLocal; // Si no tiene atributo asociado se usa este valor

    /** Constructor por defecto. */
    public Propiedad() {
    }

    public Propiedad(String nombre) {
        this(nombre, nombre);
    }

    public Propiedad(String nombre, String nombreAtributoXml) {
        this();
        setNombreCampo(nombre);
        setNombreAtributoXml(nombreAtributoXml);
    }

    @Override
    public String toString() {
        Atributo atributo = getAtributo();
        return atributo == null ? valorLocal : atributo.getTexto();
    }
                
    public final void setPropietario(Object propietario) {
        this.propietario = propietario;
    }
    
    public Atributo getAtributo() {
        if (propietario == null) { // Se trata de una propiedad no identificada
            return null;
        }
        Class clase = propietario.getClass();
        try {
            Method metodoGet = clase.getMethod(nombreCampo);
            return (Atributo) metodoGet.invoke(propietario);

        } catch (Exception ex) {
            System.err.println("No existe el metodo " + nombreCampo + " de la clase " + clase);
            ex.printStackTrace();
            return null;
        }
    }

    public String getNombreCampo() {
        return nombreCampo;
    }

    public void setNombreCampo(String nombre) {
        this.nombreCampo = nombre;
    }

    @Override
    public String getNombreAtributoXml() {
        return nombreAtributoXml;
    }

    public void setNombreAtributoXml(String nombreAtributoXml) {
        this.nombreAtributoXml = nombreAtributoXml;
    }

    /**
     * Ejecuta la asignación. Normalmente es llamada por el gestor
     * de comandos.
     */
    public void ejecutarAsignacion(String valor) {
        
        Atributo atributo = getAtributo();
        if (atributo == null) {
            return;
        }
        try {
            atributo.setTexto(valor);
            atributo.setOrigen(Atributo.ATRIBUTO);
        } catch (Exception ex) {
            Logger.getLogger(Propiedad.class.getName()).log(Level.SEVERE, null, ex);
        }

        if (propietario != null && propietario instanceof Actualizable) {
            ((Actualizable) propietario).actualizar();
        }

    }

    public boolean parsearPropiedad(String texto) {

        Atributo atributo = getAtributo();
        if (atributo == null) {
            valorLocal = texto;
            return true;
        }
        
        if (gestorComandos != null) {
            ComandoCambiarPropiedad comando = new ComandoCambiarPropiedad(this, texto, atributo.getTexto());        
            gestorComandos.ejecutar(comando);
        } else {
            ejecutarAsignacion(texto);
        }

        return true;
    }

    public boolean permitirEditarTexto() {
        return true;
    }

    public boolean permitirPulsarBoton() {
        return true;
    }

    public JComponent obtenerComponenteModificacion() {
        return null;
    }

    public void setGestorComandos(GestorComandos gestorComandos) {
        this.gestorComandos = gestorComandos;
    }

    @Override
    public String getValorAtributoXml() {
        Atributo atributo = getAtributo();
        return atributo == null ? null : atributo.getTexto();
    }
}
